package org.example.batch;

import org.apache.commons.lang3.StringUtils;
import org.example.mapper.StudentProcessedMapper;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.StepExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * MyBatis版本的Job执行监听器
 * 
 * 监听MyBatis批处理任务的执行过程，提供详细的统计和监控信息
 * 
 * @author Spring Batch + MyBatis Demo
 */
public class MyBatisJobExecutionListener implements JobExecutionListener {
    
    @Autowired
    private StudentProcessedMapper studentProcessedMapper;
    
    @Override
    public void beforeJob(JobExecution jobExecution) {
        
        System.out.println("\n🚀 MyBatis大数据量批处理任务开始执行");
        System.out.println(StringUtils.repeat('=', 60));
        // === 输出任务基本信息 ===
        String jobName = jobExecution.getJobInstance().getJobName();
        Long jobId = jobExecution.getJobId();
        
        System.out.println("📋 任务信息:");
        System.out.println("  任务名称: " + jobName);
        System.out.println("  任务ID: " + jobId);
        System.out.println("  执行时间: " + jobExecution.getStartTime());
        
        // === 输出任务参数 ===
        System.out.println("\n🔧 任务参数:");
        jobExecution.getJobParameters().getParameters().forEach((key, value) -> {
            System.out.println("  " + key + " = " + value.getValue());
        });
        
        // === 技术栈信息 ===
        System.out.println("\n🛠️ 技术栈:");
        System.out.println("  框架: Spring Batch + MyBatis");
        System.out.println("  数据源: MySQL数据库");
        System.out.println("  读取器: MyBatisPagingItemReader");
        System.out.println("  处理器: MyBatisStudentProcessor");
        System.out.println("  写入器: MyBatisStudentWriter");
        System.out.println("  持久层: MyBatis批量插入");
        
        // === 重置统计信息 ===
        MyBatisStudentProcessor.resetStatistics();
        MyBatisStudentWriter.resetStatistics();
        
        System.out.println("\n🎯 处理目标:");
        System.out.println("  • 从student表读取原始数据");
        System.out.println("  • 执行数据清洗和业务处理");
        System.out.println("  • 计算数据质量评分");
        System.out.println("  • 批量写入student_processed表");
        System.out.println("  • 提供详细的统计分析");
        
        System.out.println("\n📊 准备开始MyBatis批处理...");
        System.out.println(StringUtils.repeat('=', 60));
    }
    
    @Override
    public void afterJob(JobExecution jobExecution) {
        
        System.out.println("\n📋 MyBatis大数据量批处理任务执行完成");
        System.out.println(StringUtils.repeat('=', 60));
        
        // === 基本执行信息 ===
        String status = jobExecution.getStatus().toString();
        String exitStatus = jobExecution.getExitStatus().getExitCode();
        
        // 计算总执行时间
        long startTime = jobExecution.getStartTime().getTime();
        long endTime = jobExecution.getEndTime().getTime();
        long duration = endTime - startTime;
        
        System.out.println("📊 执行结果:");
        System.out.println("  执行状态: " + status);
        System.out.println("  退出状态: " + exitStatus);
        System.out.println("  开始时间: " + jobExecution.getStartTime());
        System.out.println("  结束时间: " + jobExecution.getEndTime());
        System.out.println("  总执行时间: " + duration + " ms (" + (duration / 1000.0) + " 秒)");
        
        // === Step执行统计 ===
        System.out.println("\n📈 Step执行统计:");
        for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
            System.out.println("  Step名称: " + stepExecution.getStepName());
            System.out.println("  读取记录数: " + stepExecution.getReadCount());
            System.out.println("  处理记录数: " + (stepExecution.getReadCount() - stepExecution.getFilterCount()));
            System.out.println("  写入记录数: " + stepExecution.getWriteCount());
            System.out.println("  跳过记录数: " + stepExecution.getSkipCount());
            System.out.println("  过滤记录数: " + stepExecution.getFilterCount());
            System.out.println("  提交次数: " + stepExecution.getCommitCount());
            System.out.println("  回滚次数: " + stepExecution.getRollbackCount());
            
            if (stepExecution.getReadSkipCount() > 0) {
                System.out.println("  读取跳过数: " + stepExecution.getReadSkipCount());
            }
            if (stepExecution.getProcessSkipCount() > 0) {
                System.out.println("  处理跳过数: " + stepExecution.getProcessSkipCount());
            }
            if (stepExecution.getWriteSkipCount() > 0) {
                System.out.println("  写入跳过数: " + stepExecution.getWriteSkipCount());
            }
        }
        
        // === 自定义处理器统计 ===
        System.out.println("\n🎯 处理器统计信息:");
        MyBatisStudentProcessor.printStatistics();
        
        // === 写入器统计 ===
        System.out.println("\n💾 写入器统计信息:");
        MyBatisStudentWriter.printDetailedStatistics();
        
        // === 数据库统计查询 ===
        try {
            String currentBatchNumber = MyBatisStudentProcessor.getCurrentBatchNumber();
            if (currentBatchNumber != null) {
                System.out.println("\n📊 数据库统计查询 (批次: " + currentBatchNumber + "):");
                Map<String, Object> dbStats = studentProcessedMapper.selectProcessStatistics(currentBatchNumber);
                
                if (dbStats != null && !dbStats.isEmpty()) {
                    System.out.println("  数据库总记录数: " + dbStats.get("total_count"));
                    System.out.println("  成功处理记录: " + dbStats.get("processed_count"));
                    System.out.println("  跳过记录数: " + dbStats.get("skipped_count"));
                    System.out.println("  错误记录数: " + dbStats.get("error_count"));
                    System.out.println("  有效数据记录: " + dbStats.get("valid_count"));
                    
                    Object avgScore = dbStats.get("avg_quality_score");
                    if (avgScore != null) {
                        System.out.println("  平均质量评分: " + String.format("%.1f", ((Number) avgScore).doubleValue()) + " 分");
                    }
                    
                    System.out.println("  批次开始时间: " + dbStats.get("start_time"));
                    System.out.println("  批次结束时间: " + dbStats.get("end_time"));
                }
            }
        } catch (Exception e) {
            System.err.println("查询数据库统计信息失败: " + e.getMessage());
        }
        
        // === 整体性能分析 ===
        System.out.println("\n⚡ 整体性能分析:");
        
        long totalRecords = jobExecution.getStepExecutions().stream()
            .mapToLong(step -> step.getReadCount())
            .sum();
        
        if (totalRecords > 0 && duration > 0) {
            double recordsPerSecond = totalRecords * 1000.0 / duration;
            double recordsPerMinute = recordsPerSecond * 60;
            double recordsPerHour = recordsPerMinute * 60;
            
            System.out.println("  处理记录数: " + totalRecords + " 条");
            System.out.println("  处理速度: " + String.format("%.2f", recordsPerSecond) + " 记录/秒");
            System.out.println("  处理速度: " + String.format("%.0f", recordsPerMinute) + " 记录/分钟");
            System.out.println("  处理速度: " + String.format("%.0f", recordsPerHour) + " 记录/小时");
            
            // 性能评估
            if (recordsPerSecond >= 1000) {
                System.out.println("  性能评级: 🌟 优秀 (≥1000记录/秒)");
            } else if (recordsPerSecond >= 500) {
                System.out.println("  性能评级: 👍 良好 (≥500记录/秒)");
            } else if (recordsPerSecond >= 100) {
                System.out.println("  性能评级: 👌 一般 (≥100记录/秒)");
            } else {
                System.out.println("  性能评级: 🐌 较慢 (<100记录/秒)");
            }
        }
        
        // === 成功/失败处理 ===
        if ("COMPLETED".equals(status)) {
            System.out.println("\n✅ MyBatis批处理任务执行成功！");
            System.out.println("🎉 数据已成功写入student_processed表");
            System.out.println("📊 可以查询该表获取处理结果和统计信息");
            
        } else if ("FAILED".equals(status)) {
            System.out.println("\n❌ MyBatis批处理任务执行失败！");
            
            System.out.println("\n�� 失败原因分析:");
            jobExecution.getAllFailureExceptions().forEach(throwable -> {
                System.err.println("  异常类型: " + throwable.getClass().getSimpleName());
                System.err.println("  异常信息: " + throwable.getMessage());
            });
            
            System.out.println("\n💡 故障排除建议:");
            System.out.println("  1. 检查数据库连接配置");
            System.out.println("  2. 确认student_processed表已创建");
            System.out.println("  3. 检查MyBatis映射文件配置");
            System.out.println("  4. 查看详细错误日志");
            
        } else {
            System.out.println("\n⚠️ 任务状态: " + status);
        }
        
        // === MyBatis特色功能说明 ===
        System.out.println("\n🛠️ MyBatis集成特色:");
        System.out.println("  ✓ 使用MyBatis XML映射文件定义SQL");
        System.out.println("  ✓ 支持复杂的查询条件和动态SQL");
        System.out.println("  ✓ 批量插入优化，提高写入性能");
        System.out.println("  ✓ 结果集自动映射到Java对象");
        System.out.println("  ✓ 支持数据库统计查询和分析");
        
        System.out.println("\n📚 扩展学习建议:");
        System.out.println("  • 学习MyBatis的动态SQL特性");
        System.out.println("  • 掌握批量操作的性能优化");
        System.out.println("  • 了解Spring Batch与ORM框架的集成");
        System.out.println("  • 实践复杂的数据处理场景");

        System.out.println(StringUtils.repeat('=', 60));
    }
}
